package org.railage.server.dao;

import java.util.List;

import org.apache.log4j.Logger;
import org.hibernate.Criteria;
import org.hibernate.Hibernate;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Order;
import org.railage.server.HibernateUtil;
import org.railage.server.entities.Trip;

public class TripDAOImpl implements TripDAO {

	private static final Logger log = Logger.getLogger(TripDAOImpl.class);

	public int addTrip(String routeName, int seatsNumber, String startTimestamp) {
		Session session = null;
		Transaction transaction = null;
		int result = -1;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			transaction = session.beginTransaction();
			Query query = session
					.createSQLQuery("select fn_add_trip(:routeName,:seatsNumber,:startTimestamp)");
			query.setString("routeName", routeName);
			query.setInteger("seatsNumber", seatsNumber);
			query.setString("startTimestamp", startTimestamp);
			result = (Integer) query.uniqueResult();
			transaction.commit();
		} catch (Exception e) {
			log.error("Error occured during Hibernate session:", e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return result;
	}

	public int deleteTrip(int tripID) {
		Session session = null;
		Transaction transaction = null;
		int result = -1;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			transaction = session.beginTransaction();
			Query query = session
					.createSQLQuery("select fn_delete_trip(:tripID)");
			query.setInteger("tripID", tripID);
			result = (Integer) query.uniqueResult();
			transaction.commit();
		} catch (Exception e) {
			log.error("Error occured during Hibernate session:", e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return result;
	}

	@SuppressWarnings("unchecked")
	public List<Trip> getAllTrips() {
		Session session = null;
		List<Trip> trips = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			Criteria criteria = session.createCriteria(Trip.class);
			criteria.addOrder(Order.asc("start"));
			trips = (List<Trip>) criteria.list();
			for (Trip trip : trips) {
				Hibernate.initialize(trip.getRoute());
			}
		} catch (Exception e) {
			log.error("Error occured during Hibernate session:", e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return trips;
	}

	@SuppressWarnings("unchecked")
	public List<Trip> getTripsByRouteName(String routeName) {
		Session session = null;
		List<Trip> trips = null;
		try {
			session = HibernateUtil.getSessionFactory().openSession();
			Query query = session
					.createQuery("from Trip where route = (from Route where name = :routeName)");
			query.setString("routeName", routeName);
			trips = (List<Trip>) query.list();
		} catch (Exception e) {
			log.error("Error occured during Hibernate session:", e);
		} finally {
			if (session != null && session.isOpen()) {
				session.close();
			}
		}
		return trips;
	}

}
